package han.chensing.latos.maker.windows.widget.timeline;

import han.chensing.latos.common.level.content.EditorConfig;
import han.chensing.latos.common.level.content.objects.CommonObject;
import han.chensing.latos.common.level.content.timeLine.TimeLineEventSet;
import han.chensing.latos.common.level.content.timeLine.TimeLineRow;
import han.chensing.latos.common.level.content.timeLine.frame.GeneralEventTypes;
import han.chensing.latos.common.level.util.ObjectUtil;
import han.chensing.latos.maker.V;

/**
 * I will write some comments in this class
 * Because I would forget some meaning of the methods
 * ):
 */
public class TimeLineWidgetUtil {

    int cachedShowedItems=-1;

    /**
     * Showed items means: the object itself and its showing rows
     * @return amount of showed items
     */
    public int getShowedItems(){
        int items=0;
        for (CommonObject commonObject : V.project.getLevelData()) {
            boolean isExpand = commonObject.getConfigAsBoolean(EditorConfig.Expand, false);
            items+=1+(isExpand?commonObject.getTimeLineRow().getAmountOfEventSets():0);
        }
        return items;
    }

    public void checkCachedShowedItems(){
        if (cachedShowedItems==-1) updateCachedShowedItems();
    }

    public void updateCachedShowedItems(){
        this.cachedShowedItems=getShowedItems();
    }

    public Selection getSelectionFromIndex(int index){
        return getSelection(i -> i == index);
    }

    public Selection getSelection(SelectionFilter selectionFilter){
        int nowAbsoluteIndex=0;
        int nowObjectIndex=0;
        for (CommonObject commonObject : V.project.getLevelData()) {
            if (selectionFilter.select(nowAbsoluteIndex))
                return new Selection(
                        commonObject,
                        null,
                        nowObjectIndex,
                        -1,
                        nowAbsoluteIndex,
                        false);
            nowAbsoluteIndex++;
            boolean isExpand = commonObject.getConfigAsBoolean(EditorConfig.Expand, false);
            if (isExpand){
                TimeLineRow timeLineRow = commonObject.getTimeLineRow();
                int timeLineEventSetIndex=0;
                for (TimeLineEventSet<?,?> timeLineEventSet : timeLineRow.getTimeLineEventSets()) {
                    if (selectionFilter.select(nowAbsoluteIndex))
                        return new Selection(
                                commonObject,
                                timeLineEventSet,
                                nowObjectIndex,
                                timeLineEventSetIndex,
                                nowAbsoluteIndex,
                                ObjectUtil.isInEnum(GeneralEventTypes.values(),timeLineEventSet.getType().name()));
                    timeLineEventSetIndex++;
                    nowAbsoluteIndex++;
                }
            }
            nowObjectIndex++;
        }
        return null;
    }

    public float getItemTotalHeight(float unitHeight){
        return getCachedShowedItems() * unitHeight;
    }

    public int getCachedShowedItems() {
        return cachedShowedItems;
    }

    public static class Selection{
        public CommonObject commonObject;
        public TimeLineRow timeLineRow;
        public TimeLineEventSet<?,?> timeLineEventSet;
        public boolean isGeneral;
        public int timeLineRowIndex;
        public int timeLineEventSetIndex;
        public int exactIndex;
        public Selection(
                CommonObject commonObject,
                TimeLineEventSet<?,?> timeLineEventSet,
                int timeLineRowIndex,
                int timeLineEventSetIndex,
                int exactIndex,
                boolean isGeneral) {
            this.exactIndex=exactIndex;
            this.commonObject=commonObject;
            this.timeLineRow = commonObject.getTimeLineRow();
            this.timeLineEventSet = timeLineEventSet;
            this.timeLineRowIndex = timeLineRowIndex;
            this.timeLineEventSetIndex = timeLineEventSetIndex;
            this.isGeneral=isGeneral;
        }
    }

    public interface SelectionFilter{
        boolean select(int nowAbsoluteIndex);
    }
}
